package com.cnpc.rightslogan.config;

import com.cnpc.rightslogan.handler.MyAuthenctiationFailureHandler;
import com.cnpc.rightslogan.handler.MyAuthenctiationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * 注意：defaultSuccessUrl不需要再配置了，实测如果配置了，成功登录的 handler 就不起作用了。
 * <p>
 * 小结
 * <p>
 * 可以看出，通过自定义的登录成功或者失败类，进行登录响应控制，可以设计一个配置，以灵活适配响应返回的是页面还是 JSON 数据。
 */

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyAuthenctiationFailureHandler myAuthenctiationFailureHandler;

    @Autowired
    private MyAuthenctiationSuccessHandler myAuthenctiationSuccessHandler;

    @Autowired
    private UserDetailsService myUserDetailsService;

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    //走自己系统的用户验证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()                                            // 定义当需要用户登录时候，转到的登录页面。
                .loginPage("/")                                         // 设置登录页面
                .loginProcessingUrl("/user/login")                      // 自定义的登录接口
                .successHandler(myAuthenctiationSuccessHandler)         // 登录成功拦截器
                .failureHandler(myAuthenctiationFailureHandler)         // 登录失败拦截器
                .defaultSuccessUrl("/successLogin").permitAll()         // 登录成功之后，默认跳转的页面
                .and().authorizeRequests()                              // 定义哪些URL需要被保护、哪些不需要被保护
                .antMatchers("/", "/api/**", "/authentication/require").permitAll()   // 设置所有人都可以访问登录页面
                .anyRequest().authenticated()                           // 任何请求,登录后可以访问
                .and().csrf().disable();                                // 关闭csrf防护
    }

    //    静态资源忽略配置
//    上述配置用户认证过程中，会发现资源文件也被安全框架挡在了外面，因此需要进行安全配置：
//    现在前端框架的静态资源完全可以通过webjars统一管理，因此注意配置/webjars/**/*
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/static/**/*", "/templates/**/*", "/**/*.css", "/**/*.js");
    }
}